<?php

namespace app\api\controller;

use support\exception\ValidateException;
use support\exception\HttpException;
use think\facade\Db;
use yzh52521\validate\Validate;
use think\Image;


class UploadController extends CommonController{
	
	
	
	/**
	* @api {post} /Upload/upload 01、图片上传
	* @apiGroup Upload
	* @apiVersion 1.0.0
	* @apiDescription  图片上传
	
	* @apiHeader {String} Authorization 用户授权token
	* @apiHeaderExample {json} Header-示例:
	* "Authorization: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOjM2NzgsImF1ZGllbmNlIjoid2ViIiwib3BlbkFJZCI6MTM2NywiY3JlYXRlZCI6MTUzMzg3OTM2ODA0Nywicm9sZXMiOiJVU0VSIiwiZXhwIjoxNTM0NDg0MTY4fQ.Gl5L-NpuwhjuPXFuhPax8ak5c64skjDTCBC64N_QdKQ2VT-zZeceuzXB9TqaYJuhkwNYEhrV3pUx1zhMWG7Org"
	
	* @apiParam (失败返回参数：) {object}     	array 返回结果集
	* @apiParam (失败返回参数：) {string}     	array.status 返回错误码  201
	* @apiParam (失败返回参数：) {string}     	array.msg 返回错误消息
	* @apiParam (成功返回参数：) {string}     	array 返回结果集
	* @apiParam (成功返回参数：) {string}     	array.status 返回错误码 200
	* @apiParam (成功返回参数：) {string}     	array.data 返回图片地址
	* @apiSuccessExample {json} 01 成功示例
	* {"status":"200","data":"操作成功"}
	* @apiErrorExample {json} 02 失败示例
	* {"status":" 201","msg":"操作失败"}
	*/
    public function upload(){
		$file = $this->request->file('file');
		$upload_config_id = $this->request->post('upload_config_id');
		$rename_type =  $this->request->post('rename',1);
		$file_type = upload_replace($this->config['filetype']); //上传黑名单过滤
		
		if(!$file || !$file->isValid()){
			throw new ValidateException('请选择正确的文件类型');
		}
		
		if(!(new Validate())->fileExt($file,$file_type)){
			throw new ValidateException('文件类型验证失败');
		}
		
		if(!(new Validate())->fileSize($file,$this->config['filesize'] * 1024 * 1024)){
			throw new ValidateException('文件大小验证失败');
		}
		
		$filepath = $this->getFile($file);
		if($filepath){
			return json(['status'=>200,'data'=>$filepath,'filestatus'=>true]);
		}else{
			$filepath = $this->getFileName($file,$rename_type);
			if($url = $this->up($file,$filepath,$upload_config_id)){
				return json(['status'=>200,'data'=>$url]);
			}
		}
	}
	
	
	//开始上传
	protected function up($file,$filepath,$upload_config_id=''){
		$hash = $this->hash('md5',$file);
		try{
			if(config('my.oss_status')){
				$url = \utils\oss\OssService::OssUpload($file,$filepath);
				$disk = config('my.oss_default_type');
			}else{
				$file->move(public_path().'/'.$filepath);
				
				if($upload_config_id){
					$this->thumb(public_path().'/'.$filepath,$upload_config_id);
				}
				
				$url = $this->config['domain'].'/'.$filepath;
				$disk = 'local';
			}
		}catch(\Exception $e){
			throw new HttpException($e->getMessage());
		}
		$data = ['filepath'=>$url,'hash'=>$hash,'create_time'=>time(),'disk'=>$disk];
		if($url && explode('/',$file->getUploadMineType())[0] == 'image'){
			$data['type'] = 1;
		}
		Db::name('file')->insert($data);
		return $url;
	}
	
	
	//获取上传的文件完整路径
	private function getFileName($file,$rename_type){
		if($rename_type == 1){
			return 'uploads/'.$this->request->app.'/'.date(config('my.upload_subdir')).'/'.$this->hash('md5',$file).'.'.$file->getUploadExtension();
		}else{
			return 'uploads/'.$this->request->app.'/'.date(config('my.upload_subdir')).'/'.$file->getUploadName();
		}
	}
	
	
	//检测数据库的同图片的路径是否存在 存在则返回
	private function getFile($file){
		$filepath = Db::name('file')->where('hash',$this->hash('md5',$file))->value('filepath');
		if($filepath  && config('my.check_file_status')){
			return $filepath;
		}
	}
	
	
	//生成缩略图
	private function thumb($imagesUrl,$upload_config_id){				
		$configInfo = Db::name("upload_config")->where('id',$upload_config_id)->find();
		if($configInfo){ 
			$image = Image::open($imagesUrl);
			$targetimages = $imagesUrl;
			
			//当设置不覆盖,生成新的文件
			if(!$configInfo['upload_replace']){
				$fileinfo = pathinfo($imagesUrl);
				$targetimages = $fileinfo['dirname'].'/s_'.$fileinfo['basename'];
				copy($imagesUrl,$targetimages);
			}
			
			//生成缩略图
			if($configInfo['thumb_status']){
				$image->thumb($configInfo['thumb_width'], $configInfo['thumb_height'],$configInfo['thumb_type'])->save($targetimages);
			}
			
			//生成水印
			if($this->config['water_status'] && $this->config['water_position']){
				$image->water(public_path().'/'.config('my.water_img'),$this->config['water_position'],$this->config['water_alpha'])->save($targetimages); 
			}
		}
	}
	
	
	/**
     * 获取文件的哈希散列值
     * @access public
     * @param string $type
     * @return string
     */
    public function hash(string $type,$file): string
    {
        return hash_file($type, $file->getRealPath());
    }
	

}
